#include "ADS1247.h"
#include "spi.h"
#include "tim.h"

/*****************************************************************************/
#define ADS1247_MAX_SAMPLES         100
#define ADS1247_LIMIT_ADSDATA       0X1000
#define ADS1247_START               0X01
#define ADS1247_MIDDLE              0X02
#define ADS1247_FINISH              0X03

//ADS1247内部命令
#define ADS1247_CMD_WAKEUP      0X00    //唤醒
#define ADS1247_CMD_SLEEP       0X02    //睡眠
#define ADS1247_CMD_RESET       0X06    //复位
#define ADS1247_CMD_NOP         0XFF    //空指令
#define ADS1247_CMD_RDATA       0X12    //读一次数据
#define ADS1247_CMD_RDATAC      0X14    //连续读数据
#define ADS1247_CMD_SDATAC      0X16    //停止连续读数据
#define ADS1247_CMD_RREG        0X20    //读寄存器字节1
#define ADS1247_CMD_WREG        0X40    //写寄存器字节
#define ADS1247_CMD_SYSOCAL     0X60    //系统偏移校准
#define ADS1247_CMD_SYSGCAL     0X61    //系统增益校准
#define ADS1247_CMD_SELFOCAL    0X62    //自偏移校准

//ADS1247内部寄存器地址
#define ADS1247_REG_MUX0           0X00
#define ADS1247_REG_VBIAS          0X01
#define ADS1247_REG_MUX1           0X02
#define ADS1247_REG_SYS0           0X03
#define ADS1247_REG_OFC0           0X04
#define ADS1247_REG_OFC1           0X05
#define ADS1247_REG_OFC2           0X06
#define ADS1247_REG_FSC0           0X07
#define ADS1247_REG_FSC1           0X08
#define ADS1247_REG_FSC2           0X09
#define ADS1247_REG_IDAC0          0X0A
#define ADS1247_REG_IDAC1          0X0B
#define ADS1247_REG_GPIOCFG        0X0C
#define ADS1247_REG_GPIODIR        0X0D
#define ADS1247_REG_GPIODAT        0X0E

//ADS1247内部自校准
//偏移校准0x000000
#define ADS1247_OFC_0               0X00
#define ADS1247_OFC_1               0X06
#define ADS1247_OFC_2               0XAB
//增益校准0x400000
#define ADS1247_FSC_0               0X40
#define ADS1247_FSC_1               0X00
#define ADS1247_FSC_2               0X00

#define Nop5    {__NOP();__NOP();__NOP();__NOP();__NOP();}      //5个Nop延时

/*******************************************************************************
* 函数名  : SPI1_Send_Byte
* 描述    : SPI1发送1个字节数据
* 输入    : dat:待发送的数据
* 返回值  : 返回收到的数据
*******************************************************************************/
u8 ADS1247SPI(u8 data)
{
    u8 wait_cnt=0;
    while(!LL_SPI_IsActiveFlag_TXE(SPI2))        //等待数据发送完成
    {
        if(wait_cnt++ >100)	break;
    }
    LL_SPI_TransmitData8(SPI2, data);            //发送8位数据
    wait_cnt = 0;
    while(!LL_SPI_IsActiveFlag_RXNE(SPI2))       //等待接收缓存非空
    {
        if(wait_cnt++ >100)	break;
    }
    return LL_SPI_ReceiveData8(SPI2);            //返回SPI2接收到的数据
}

//ADS1248 写数据到寄存器
void ADS1247WREG(u8 regaddr,u8 databyte)
{
    //向寄存器写入数据地址
    ADS1247SPI(ADS1247_CMD_WREG|(regaddr & 0x0F));Nop5;
    //写入数据的个数n-1
    ADS1247SPI(0);Nop5;
    //向regaddr地址指向的寄存器写入数据databyte
    ADS1247SPI(databyte);Nop5;
}

void ADS1247_Init(void)
{
    MX_SPI2_Init();    //IO 和 SPI 初始化

    //芯片复位
    AD_CS(0);        //选通AD
    AD_RST(0);       //复位管脚置低电平
    delay_us(200);   //650
    AD_RST(1);       //复位管脚置高电平
    delay_us(400);  //1300

    //芯片初始化

    //初始化MUX0多路复用控制寄存器
    //00000001,Bit7-6:传感器电流源检测不使用，Bit5-3:正输入为AIN0，Bit2-0:负输入为AIN1
    ADS1247WREG(ADS1247_REG_MUX0,0x13); Nop5;

    //初始化VBIAS偏压寄存器
    //00000000,Bit7-0:偏置电压选择关闭（默认）
    //ADS1247WREG(ADS1247_REG_VBIAS,0xFF);       Delay(100);
    ADS1247WREG(ADS1247_REG_VBIAS,0); Nop5;

    //初始化MUX1多路复用控制寄存器
    //00110000,Bit7：启用内部晶振，Bit6-5:内部基准一直打开，Bit4-3:输入基准为片上基准，Bit2-0:普通模式
    ADS1247WREG(ADS1247_REG_MUX1,0x30);    //恢复正常模式   外部REF0  60000
    //  ADS1247WREG(ADS1247_REG_MUX1,0x28);  //恢复正常模式   外部REF1
    //  ADS1247WREG(ADS1247_REG_MUX1,0x30);  //恢复正常模式   内部2.048

    delay_us(10000);  //延时等待10ms，等待内部基准稳定

    //初始化SYS0系统控制寄存器
    //00000000，Bit7:必须设置为0，Bit6-41：选择1倍增益，Bit3-0：选择1000SPS测量速度
    //ADS1247WREG(ADS1247_REG_SYS0,0x08);     Delay(10); //1000SPS
    //ADS1247WREG(ADS1247_REG_SYS0,0x07);     Delay(10); //640SPS
    //ADS1247WREG(ADS1247_REG_SYS0,0x06);     Delay(10); //320SPS
    //ADS1247WREG(ADS1247_REG_SYS0,0x05);     Delay(10); //160SPS
    //ADS1247WREG(ADS1247_REG_SYS0,0x04);     Delay(10); //80SPS
    //ADS1247WREG(ADS1247_REG_SYS0,0x23);     Delay(10); //40SPS
    ADS1247WREG(ADS1247_REG_SYS0,0x32);       delay_us(50); //20SPS
    //ADS1247WREG(ADS1247_REG_SYS0,0x21);     Delay(10); //10SPS
    //ADS1247WREG(ADS1247_REG_SYS0,0x00);     Delay(10); //5SPS


    //初始化IDAC0控制寄存器
    //00000110,Bit7-4:只读，Bit3:DRDY/DOUT功能不复用Dout线 ，Bit2-0:打开内部0.5mA恒流源
    ADS1247WREG(ADS1247_REG_IDAC0,0x04);     Nop5;   //铂电阻 恒流源0.5mA
    //ADS1247WREG(ADS1247_REG_IDAC0,0x03);    Delay(10);  //铂电阻 恒流源0.25mA

    //初始化IDAC1控制寄存器
    //11111111,Bit7-4:打开内部第二恒流源的连接，Bit3-0:打开内部第一恒流源的连接
    ADS1247WREG(ADS1247_REG_IDAC1,0x01);     Nop5;

    //   ADS1247WREG(ADS1247_REG_GPIOCFG,0x03);     Delay(10); //配置P0和P1使能
    //   ADS1247WREG(ADS1247_REG_GPIODIR,0x00);     Delay(10); //配置P0和P1为输出口
    //   ADS1247WREG(ADS1247_REG_GPIODAT,0x00);     Delay(10); //使能P0和P1输出00

    delay_us(33);AD_CS(1);    //取消选通ADS1247
}

/*******************************************************************************
ADS1247 AD读取
Channel:读取AD通道号
Channel = 0x00----0x07对应AD0---AD7通道    00 10 11 01
*/
void ADS1247_ReadAD(u8 ucChannel)
{
    AD_CS(0);Nop5;;
    ADS1247SPI(ADS1247_CMD_RDATA);Nop5;  //发送单次读数据命令
    CJ.ucREG[3+ucChannel*4] = 0;
    CJ.ucREG[2+ucChannel*4] = ADS1247SPI(ADS1247_CMD_NOP);Nop5;  //读取AD数据,先高位，后低位
    CJ.ucREG[1+ucChannel*4] = ADS1247SPI(ADS1247_CMD_NOP);Nop5;  //读取AD数据,先高位，后低位
    CJ.ucREG[0+ucChannel*4] = ADS1247SPI(ADS1247_CMD_NOP);Nop5;  //读取AD数据,先高位，后低位
    Nop5;AD_CS(1);
}

void ADS1247_RST(void)
{
    AD_CS(0);Nop5;
    AD_RST(0);     //复位管脚置低电平
    delay_us(200);
    AD_RST(1);     //复位管脚置高电平
    delay_us(400);
    // ADS1247SPI(ADS1247_CMD_WAKEUP);nop5;    //唤醒ADS1247
    ADS1247WREG(ADS1247_REG_VBIAS,0);Nop5;
    ADS1247WREG(ADS1247_REG_MUX1,0x30);Nop5;
    delay_us(50);
    Nop5;AD_CS(1);
}

void ADS1247_STA(u8 ucChannel)
{
    AD_STA(1);     //STA 开始转换，选通ADS1247
    AD_CS(0);Nop5;

    ADS1247WREG(ADS1247_REG_SYS0,AIMD.ucPGA[ucChannel]);       //转换速率 和 放大倍数
    ADS1247WREG(ADS1247_REG_MUX0,0x13);

    if (AIMD.ucAITypeA[ucChannel] == 1)     //热电偶传感器
    {
        ADS1247WREG(ADS1247_REG_MUX1,0x30);     //内部基准打开，使用内部REF
    }
    else if(AIMD.ucAITypeA[ucChannel] == 2) //铂电阻传感器
    {
        if(AIMD.ucAITypeB[ucChannel] == 0)        //通道为PT100
        {
            //ADS1247WREG(ADS1247_REG_IDAC0,0x04); nop5;  //初始化IDAC0控制寄存器 PT100 500uA
            ADS1247WREG(ADS1247_REG_MUX1,0x20);              //内部基准打开，使用外部REF0
        }
        else if(AIMD.ucAITypeB[ucChannel] == 1)  //通道为PT1000
        {
            // ADS1247WREG(ADS1247_REG_IDAC0,0x03); nop5;  //初始化IDAC0控制寄存器 PT1000  250uA
            ADS1247WREG(ADS1247_REG_MUX1,0x20);              //内部基准打开，使用外部REF0
        }
    }
    else if(AIMD.ucAITypeA[ucChannel] == 3)  //电压
    {
        ADS1247WREG(ADS1247_REG_MUX1,0x30);     //内部基准打开，使用内部REF
    }
    else if(AIMD.ucAITypeA[ucChannel] == 4)  //电流
    {
        ADS1247WREG(ADS1247_REG_MUX1,0x30);     //内部基准打开，使用内部REF
    }
    Nop5;AD_CS(1);AD_STA(0);
}

void ADS1247_STA2(u8 ucChannel)
{
    AD_STA(1);     //STA 开始转换，选通ADS1247
    AD_CS(0);Nop5;

//    ADS1247SPI(ADS1247_CMD_WAKEUP);nop5;    //唤醒ADS1247

    if(AIMD.ucAITypeB[ucChannel] == 0)        //通道为PT100
    {
        ADS1247WREG(ADS1247_REG_IDAC0,0x04);   //初始化IDAC0控制寄存器 PT100 500uA
    }
    else if(AIMD.ucAITypeB[ucChannel] == 1)  //通道为PT1000
    {
        ADS1247WREG(ADS1247_REG_IDAC0,0x03);   //初始化IDAC0控制寄存器 PT1000  250uA
    }

    ADS1247WREG(ADS1247_REG_SYS0,0x04);    //放大倍数1 和 转换速率160

    //铂电阻传感器 断线检测测量 参数配置
    ADS1247WREG(ADS1247_REG_MUX1,0x35);    //内部基准打开，使用内部REF

    Nop5;AD_CS(1); AD_STA(0);
}
